/*
 * Copyright (C) 2017-2018 Alibaba Group Holding Limited. All Rights Reserved.
 *
 *
 * Licensed under the Apache License, Version 2.0 (the License);
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifndef ALIOS_SPEECH_STT_H_
#define ALIOS_SPEECH_STT_H_

#include <stdint.h>
#include <string>
#include <memory>
#include <asr/speech_const.h>

/**
 * @file stt.h
 * @brief This file contains STTCloudEngine public interface defined by AliOS,
 * and is shared by the platform independent voice framework and the vendor specific Implementation.
 **/

namespace alios {

class STTCloudEngineListener {
public:
  STTCloudEngineListener() {}
  virtual ~STTCloudEngineListener() {}

public:
    /**
    * @brief stt认证结果
    * @param status 认证结果，true表示成功， false表示失败
    * @return
    */
    virtual void OnAuthResult(const std::string& vendor, bool status) = 0;

  /**
   * @brief notify STTCloudEngineListener recoginition result
   * when STTCloudEngine have recoginition result
   * @param[result] result string of recoginition
   * @param[result_state] state for result of recoginition
   */
  virtual void OnRecognitionResult(AsrResultState result_state, const std::string &result) = 0;

  /**
   * @brief notify STTCloudEngineListener recognition result error
   * when STTCloudEngine have recognition result error.
   * @param[result_state] state for result of recognition
   * @param[error] for error reason code
   */
  virtual void OnRecognitionError(AsrErrorCode error, std::string &error_info) = 0;
};

class STTCloudEngine {
public:
  STTCloudEngine() {}
  virtual ~STTCloudEngine() {}
public:
  /**
   * @brief SetQueryId to STTCloudEngine for identify stt session.
   * @param[query_id] uuid for STTCloudEngine identify asr process id
   * its content should be contained in asr result value with uid key.
   */
  virtual void SetQueryId(std::string &query_id) = 0;

  /**
   * @brief SetVocabulary for STTCloudEngine
   * @return
   * @param[vocabulary] vocabulary for STTCloudEngine
   * its content is json format {"word":weight} ,
   * weight 1-5
   * for example:
   * {"关羽":5,"张飞":5,"赵云":5}
   * it must be enabled when next calls for startVoice
   */
  virtual void SetVocabulary(JSON &vocabulary) = 0;

  /**
   * @brief set asr listener for  STTCloudEngine
   * @return
   * @param[listener] listener for STTCloudEngine
   */
  virtual void SetListener(STTCloudEngineListener *listener) = 0;

  // initialize the asr cloud engine.
  /**
   * @brief initialize STTCloudEngine
   * @param[configs] for STTCloudEngine config infos
   * its content is json format
   * for example:
   * '{"configs":{"auth":{"uuid":"12345678","device":"AS22MC","version":"2.3.1"},
   *  "i18n":{"lang":"zh-CN"}}}
   * it maybe called before Start and once
   * if engine impl use auth config and chek fail, it should notify
   * in listener with error.
   * if framework change auth config, it'll call UpdateConfigs and
   * engine impl should use new configs and check again.
   * @return[retcode] return STTCloudEngine result for Initialize.
   */
  virtual RetCode Initialize(JSON configs) { return alios::FuncNoSupport; }

  /**
   * @brief uninitialize to STTCloudEngine
   */
  virtual RetCode Uninitialize() { return alios::FuncNoSupport; }

  // update configure infos.
  /**
   * @brief update system config info for STTCloudEngine
   * @param[configs] for STTCloudEngine sys config infos
   * its content is json format
   * for example:
   * '{"configs":{"auth":{"uuid":"12345678", "device":"AS22MC", "version":"2.3.1"},
   *  "network":{"net_type": 1, "conn_state": 0},
   *  "fullduplex":{"enable": 1, "min_confidence": 0.2}}}'
   * it can be called many times, and only with some fields to change.
   * if engine impl use auth config and chek again, if check fail, it should notify
   * in listen with error.
   * @return.
   */
  virtual void UpdateConfigs(JSON configs) {}

  /**
   * @brief called when start begin, to connect, build and send protocal header etc.
   * @return
   */
  virtual void Start() = 0;

  /**
   * @brief update voice if new data available
   * @return
   * @param[encoder] encoder - data format of voice
   * @param[data] data
   * @param[length] length
   */
  virtual void UpdateVoiceData(const AudioEncoder encoder, const int8_t *data, const int length) = 0;

  /**
   * @brief called when voice end,to tell the server stop.
   * @return
   */
  virtual void Stop() = 0;

  /**
   * @brief to cancel this session of STT. OnRecognitionResult or OnRecognitionError should be invoked later.
   * @return
   */
  virtual void Cancel() = 0;
};
}  // namespace alios

#if __GNUC__ >= 4
#  define ASR_EXPORT_API __attribute__ ((visibility ("default")))
#  define ASR_IMPORT_API __attribute__ ((visibility ("default")))
#  define ASR_INTERNAL   __attribute__ ((visibility ("hidden")))
#else
/** Visibility attribute to show method definitions */
#  define ASR_EXPORT_API
/** Visibility attribute to show declarations */
#  define ASR_IMPORT_API
/** Visibility attribute to hide declarations */
#  define ASR_INTERNAL
#endif

#define STT_CREATECLOUDENGINE_SYM "STT_CreateCloudEngine"
#define STT_DESTROYCLOUDENGINE_SYM "STT_DestroyCloudEngine"

/*----------------------------------------------------------------------*/
/*                        Function Prototypes                           */
/*----------------------------------------------------------------------*/
#ifdef __cplusplus
extern "C" {
#endif

//
// STT Engine library default entries.
// STT_CreateCloudEngine/STT_DestroyCloudEngine.
//

typedef alios::STTCloudEngine* (*STT_CreateCloudEngineFunc)(void);
typedef alios::RetCode (*STT_DestroyCloudEngineFunc)(alios::STTCloudEngine* engine);

#ifdef __cplusplus
}  /* end extern "C" */
#endif

#endif  // ALIOS_SPEECH_STT_H_
